package com.ea.eadp.nexus.test.common.ApiClients;

import com.ea.eadp.nexus.test.common.HttpsClient;
import com.ea.eadp.nexus.test.common.TestUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.*;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.Map;

/**
 * Created by ChuanYe on 7/24/2014.
 */
public abstract class NexusApiBase {
    protected final Log log = LogFactory.getLog(getClass());
    protected DefaultHttpClient client;
    //protected Map<String, HttpsClient> httpsClients;

    protected HttpResponse post(HttpPost post, HttpContext httpContext) throws Exception {
        log.info("POST: " + post.getURI());
        for (Header h : post.getAllHeaders()) {
            log.info("HEADER: " + h.getName() + "=" + h.getValue());
        }
        HttpResponse response = client.execute(post, getResponseHandler(),httpContext);
        if (httpContext != null) {
            log.info("RESPONSE: " + TestUtil.getCurrentUrl(httpContext));
        }
        log.info("RESPONSE: " + response.getStatusLine().getStatusCode());
        return response;
    }

    protected HttpResponse post(HttpPost post, HttpContext httpContext, String keyStoreName) throws Exception {
        log.info("POST: " + post.getURI());
        HttpsClient client = NexusHttpClients.getHttpsClient(keyStoreName);
        for (Header h : post.getAllHeaders()) {
            log.info("HEADER: " + h.getName() + "=" + h.getValue());
        }
        log.info("BODY: " + IOUtils.toString(post.getEntity().getContent()));
        HttpResponse response = client.execute(post, getResponseHandler(),httpContext);
        if (httpContext != null) {
            log.info("RESPONSE: " + TestUtil.getCurrentUrl(httpContext));
        }
        log.info("RESPONSE: " + response.getStatusLine().getStatusCode());
        return response;
    }

    protected HttpResponse put(HttpPut put, HttpContext httpContext) throws Exception {
        log.info("PUT: " + put.getURI());
        for (Header h : put.getAllHeaders()) {
            log.info("HEADER: " + h.getName() + "=" + h.getValue());
        }
        log.info("BODY: " + IOUtils.toString(put.getEntity().getContent()));
        HttpResponse response = client.execute(put, getResponseHandler(),httpContext);
        if (httpContext != null) {
            log.info("RESPONSE: " + TestUtil.getCurrentUrl(httpContext));
        }
        log.info("RESPONSE: " + response.getStatusLine().getStatusCode());
        return response;
    }

    protected HttpResponse get(HttpGet get, HttpContext httpContext) throws Exception {
        log.info("GET: " + get.getURI());
        for (Header h : get.getAllHeaders()) {
            log.info("HEADER: " + h.getName() + "=" + h.getValue());
        }
        HttpResponse response = client.execute(get,getResponseHandler(), httpContext);
        if (httpContext != null) {
            log.info("RESPONSE: " + TestUtil.getCurrentUrl(httpContext));
        }
        log.info("RESPONSE: " + response.getStatusLine().getStatusCode());
        return response;
    }

    protected HttpResponse delete(HttpDelete delete, HttpContext httpContext) throws Exception {
        log.info("DELETE: " + delete.getURI());
        for (Header h : delete.getAllHeaders()) {
            log.info("HEADER: " + h.getName() + "=" + h.getValue());
        }
        HttpResponse response = client.execute(delete,getResponseHandler(), httpContext);
        if (httpContext != null) {
            log.info("RESPONSE: " + TestUtil.getCurrentUrl(httpContext));
        }
        log.info("RESPONSE: " + response.getStatusLine().getStatusCode());
        return response;
    }

    public HttpResponse execute(HttpRequestBase httpRequestBase, HttpContext httpContext) throws Exception {
        if (httpRequestBase != null) {
            log.info(httpRequestBase.getClass().toString() + " URL: " + httpRequestBase.getURI());
        }
        for (Header h : httpRequestBase.getAllHeaders()) {
            log.info("HEADER: " + h.getName() + "=" + h.getValue());
        }
        HttpResponse response = client.execute(httpRequestBase,getResponseHandler(), httpContext);
        if (httpContext != null) {
            log.info("RESPONSE: " + TestUtil.getCurrentUrl(httpContext));
        }
        log.info("RESPONSE: " + response.getStatusLine().getStatusCode());
        return response;
    }

    public ResponseHandler<HttpResponse> getResponseHandler(){
        ResponseHandler<HttpResponse> responseHandler = new ResponseHandler<HttpResponse>() {
            @Override
            public HttpResponse handleResponse( HttpResponse response) throws IOException {
                HttpEntity entity=response.getEntity();
                if (entity!=null){
                    response.setEntity(new BufferedHttpEntity(entity));
                    EntityUtils.consume(entity);
                }
                return response;
            }
        };
        return responseHandler;
    }
}
